import os
import sys
import subprocess
import copy
import logging

sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))

from base.context import Context
from utils.common_utils import *
from configure.compiler_configure import *
from command_parser.ld_parse.ld_command_parser import LDParser
from utils.db_object_pool import DBObjectPool
from configure.config_logging import capture_log_init

class LD_Handler(object):
    def __init__(self, command):
        self.context = Context()
        self.env = {}
        self.cwd = ""
        self.command = command
        self.capture_db_handler = None
        self.cache_db_handler = None
    
    def init_env(self):
        self.cwd = os.getcwd()
        self.env = dict(os.environ)
        remove_envs_by_keys(env=self.env,remove_list=["LD_PRELOAD"])
        self.context.update_work_path(os.path.dirname(self.env["IRGEN_WORK_PATH"]))
        self.init_logger()
        self.context.check_redis_cached_config()
        self.capture_db_handler = DBObjectPool.get_db_inst_by_name("ld")
    
    def init_logger(self):
        capture_log_init(log_dir=self.context.LOG_DIR, log_mode="a", log_name="ld.log", log_level="DEBUG")
    
    def run_ld_handler(self):
        
        logging.debug("Orignal LD Command  %s" % ' '.join(self.command))
        
        parser = LDParser(context=self.context, command=self.command, cwd=self.cwd)
    
        linker, options = parser.parse_command()
        
        self.linker = real_binary_path(linker)
        
        parser.auto_check_output_options()
        
        command_line = parser.get_original_command()
        # active_cache_env(env=self.env, context=self.context)
        ret = run_command(command=command_line, env=self.env)
        if ret:
            logging.warning("LD command: {} Failed".format(' '.join(command_line)))
        else:
            logging.debug("Record command: {}".format(' '.join(command_line)))
            # print("[INFO] Capture LD Command: %s" % ' '.join(command_line))
        self.record_command(parser=parser)
        return ret
    
    def record_command(self, parser=None):
        output = parser.get_output_options()
        real_output = os.path.abspath(output[0].parameter[0])
        
        command = parser.get_original_command()
        
        input_options = parser.get_input_options()
        input_files = [os.path.abspath(opt.parameter[0]) for opt in input_options if not is_sys_obj(opt.parameter[0])]
        self.save_dep_info(output=real_output, command=command, input_files=input_files)

    def save_dep_info(self, output="", command=[], input_files=[]):
        
        output_md5 = file_md5(file_path=output)
        if not output_md5:
            return
        
        self.capture_db_handler.set_name_dep(name_md5=output_md5, name=output)
        
        input_files_md5 = []
        for file in input_files:
            f_md5 = file_md5(file)
            if f_md5:
                input_files_md5.append(f_md5)
                self.capture_db_handler.set_name_dep(name_md5=f_md5, name=file)
        
        self.capture_db_handler.set_cmd_dep(name_md5=output_md5, cmd=[self.cwd, command])
        self.capture_db_handler.set_link_dep(name_md5=output_md5, links=input_files_md5)
    
if __name__ == "__main__":
    
    command = sys.argv[2:]
    handler = LD_Handler(command)
    
    handler.init_env()
    handler.run_ld_handler()
        
        
        
        